package dynamic_demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 优化版的动态代理类
 * <p>
 * 新增的无参的 getProxy 方法避免了代理类的的传入，并且用了泛型避免了强制类型转换
 * <p>
 * 思考：还能再优化吗？目前还有什么缺陷？
 * 优点：虽然与静态代理类相比好了很多，当接口变动，这个动态代理类不需要改变。
 * 缺点：但是，当要代理一个没有任何接口的类，这个动态代理类就无用武之地了！
 *
 * @Author: Crystal
 * @Date: 2018/11/28 16:28
 **/
public class BetterDynamicProxy implements InvocationHandler {

    private Object target;

    public BetterDynamicProxy(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy() {
        return (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this
        );
    }

    private void before() {
        System.out.println("##### Before ######");
    }

    private void after() {
        System.out.println("##### After ######");
    }

    public static void main(String[] args) {
        BetterDynamicProxy dynamicProxy = new BetterDynamicProxy(new HelloImpl());
        Hello helloProxy = dynamicProxy.getProxy();
        helloProxy.say("Better Dynamic Cyy");

    }
}
